const util = require("util") ,
    Logger = require("./Logger")
    // Emitter = require('events')
const DefaultConfig = require("./DefaultConfig")  

// const { DefaultConfig , Middleware } = require("./index")

// const log = util.debuglog("SpringBreeze")

global._SERVICE = {}

class App {

    constructor( opt ){
        //注入配置项
        this.config( opt || {} )
        //初始化运行时内容及属性
        this.init()
    }

    /**
     *  设置/获取配置项
     * @param {*} opt 
     */
    config( opt ){
        if( !opt ) return this.RuntimeConfig 
        //覆盖配置,并注入到RuntimeConfig 
        this.RuntimeConfig = Object.assign( DefaultConfig , opt )
    }

    init( ) {
        //加载Logger
        Logger.init() 
            
        //分析需要加载的中间件
        this.Middleware = []
        const middlewares = this.RuntimeConfig.middlewares
        for( let idx in middlewares ){
            const middleware = middlewares[ idx ]
            this.use( middleware )
        }
    }

    /**
     *  通过该接口提取和设置中间件服务
     * @param {*} key
     * @param {*} s 
     */
    service( key , s ){
        if( !s ) return global._SERVICE[ key ]
        global._SERVICE[ key ] = s
    }

    /**
     *  传入参数为middleware的配置文件
     * @param {*} middleware 
     *      name
     *      require
     *      desc
     */
    use( middleware ){

        const name = middleware.name 
        let entityFile = middleware.require
        try{
            if( typeof( entityFile) == "string")
                entityFile = require( entityFile )  
            //TODO 检查是否为Object
            const entity = new entityFile() 
            // if( entity instanceof Middleware ){
            //添加中间件,必须继承 Middleware ,实现相应的约束
            entity.name( name )
            entity.config( middleware )
            entity.service( global._SERVICE )
            this.Middleware.push({
                name : name ,
                entity : entity 
            })
            // }else this.onerror( new Error("插件必须符合Middleware的规范," + name ))
        }catch(e){
            Log.error( "[%s]加载失败,[%s]" , entityFile , e )
            this.onerror( e )
        }
    }

    error( fn ) {
        //覆盖原生的err处理函数
        this.onerror = fn 
    }

    /**
     *  监听异常
     * @param {*} err 
     */
    onerror( err ){
        GetLogger("err").error( err )
        throw err 
    }

    async doMiddleware( fns , idx ) {
        const app = this 
        const len = fns.length 
        if( idx == len ) {
            Log.info("->中间件加载任务完成,共加载[%d]个中间件." , idx )
            //清空临时记录
            delete this.Middleware
            return 
        }     //finished .
        const middleware = fns[ idx ]       //根据索引去除
        const name = middleware.name
        Log.info("-->加载中间件[%d][%s]" , idx , name )
        //提取中间件对应的配置
        const mdw = middleware.entity

        try{
            
            mdw.before()
            mdw.start().then( function(){
                app.service( name , mdw )
                app.doMiddleware( fns , idx + 1 )
            }).catch( app.onerror )
            
        }catch(e){
            await this.onerror( e )
        }
        await mdw.final()
    }

    async start() {
        Log.info("开始启动SpringBreeze...")
        const len = this.Middleware.length 
        Log.info("->准备加载中间件,共发现中间[%d]个" , len )
        //开始启动中间件服务,顺序阻塞启动
        this.doMiddleware( this.Middleware , 0 , len )
    }

}

module.exports = App 